#ifndef NETCLIENT_H
#define NETCLIENT_H
#include<QObject>
#include<QNetworkAccessManager>
#include<QWebSocket>
#include<QProtobufSerializer>
#include<QNetworkRequest>
#include<QNetworkReply>
#include<iostream>

#include"../debug.h"
#include"../model/data.h"

namespace model{
class DataCenter;
}

namespace network{

class NetClient : public QObject{
    Q_OBJECT
public:
    NetClient(model::DataCenter* dataCenter);
    //~NetClient();

    ///////////////////////////////////////////////////////////
    /// WebSocket部分
    ///////////////////////////////////////////////////////////

    //初始化webSocket
    void initWebSocket();

    //创建请求ID
    QString makeRequestId();

    //发送身份信息
    void sendAuthentication();

    //处理WebSocket收到的数据
    void handleWsResponse(std::shared_ptr<lx::NotifyMessage>& notifyMessage);

    //处理WebSocket收到的会话消息
    void handleWsMessage(const model::Message& message);

    //处理删除好友请求
    void handleWsRemoveFriend(const QString &userId);

    //处理添加好友请求
    void handleWsAddFriendApply(const model::UserInfo& userInfo);

    //处理添加删除好友结果
    void handleWsAddAndRejectFriendProcess(const model::UserInfo& userInfo, bool agree);

    //处理创建会话
    void handleWsSessionCreate(const model::ChatSessionInfo& chatSessionInfo);

    //关闭webSocket连接
    void closeWebSocket();


    ///////////////////////////////////////////////////////////
    /// http部分
    ///////////////////////////////////////////////////////////

    //进行网络测试
    void ping();

    //通过这个⽅法统⼀构造 HTTP 请求
    QNetworkReply* sendHttpRequest(const QString& apiPath, const QByteArray& body);

    // 通过这个⽅法统⼀处理 HTTP 响应
    template<class T>
    std::shared_ptr<T> handleHttpResponse(QNetworkReply* httpResp);

    //获取个人信息
    void getMyselfInfo(const QString& loginSessionId);

    //获取好友列表
    void getFriendList(const QString& loginSessionId);

    //获取会话列表
    void getSessionList(const QString& loginSessionId);

    //获取好友申请列表
    void getApplyList(const QString& loginSessionId);

    //获取最近消息
    void getRecentMessages(const QString& loginSessionId, const QString& chatSessionId, bool isUpdateUI);

    //发送消息
    void sendMessage(const QString& loginSessionId, const QString& chatSessionId, model::MessageType type, const QByteArray& content,
                     const QString& extraInfo);

    //修改名字
    void changeNickName(const QString& loginSessionId, const QString& name);

    //修改标签
    void changeDescription(const QString& loginSessionId, const QString& description);

    //修改手机号码
    void getVerifyCode(const QString& phone);
    void changePhone(const QString& loginSessionId, const QString& phone, const QString& verifyCodeId, const QString& verifyCode);

    //修改头像
    void changeAvatar(const QString& loginSessionId, const QByteArray& avatar);

    //删除好友
    void deleteFriend(const QString& loginSessionId, const QString& userId);

    //好友申请
    void addFriendApply(const QString& loginSessionId, const QString& userId);

    //同意好友申请
    void acceptFriendApply(const QString& loginSessionId, const QString& userId);

    //拒绝好友申请
    void rejectFriendApply(const QString& loginSessionId, const QString& userId);

    //创建会话
    void createChatSession(const QString& loginSessionId, const QList<QString>& userIdList);

    //获取群聊成员信息
    void getMemberList(const QString& loginSessionId, const QString& chatSessionId);

    //搜索用户
    void searchUser(const QString& loginSessionId, const QString& searchKey);

    //搜索历史消息
    //按照关键字搜索历史消息
    void searchMessage(const QString& loginSessionId, const QString& chatSessionId, const QString& searchKey);
    //按照时间搜索历史消息
    void searchMessageByTime(const QString& loginSessionId, const QString& chatSessionId, const QDateTime begTime, const QDateTime endTime);

    //用户账号和密码登录注册
    //用户登录
    void userLogin(const QString& username, const QString& password);
    //用户注册
    void userRegister(const QString& username, const QString& password);

    //通过手机号和手机验证码登录注册
    void phoneLogin(const QString& phone, const QString& phoneVerifyCode);
    void phoneRegister(const QString& phone, const QString& phoneVerifyCode);

private:
#if CONNECT_TEST_SERVER
    const QString HTTP_URL = "http://127.0.0.1:8088";
    const QString WEBSOCKET_URL = "ws://127.0.0.1:8089/ws";
#else
    const QString HTTP_URL = "http://47.108.169.126:9001";
    const QString WEBSOCKET_URL = "ws://47.108.169.126:9000/ws";
#endif

    QNetworkAccessManager httpClient;
    QWebSocket webSocketClient;
    model::DataCenter* dataCenter;

    // 序列化器
    QProtobufSerializer serializer;
};

}
#endif // NETCLIENT_H
